import {Injectable, OnDestroy} from '@angular/core';
import {Router, ActivatedRoute, NavigationEnd} from '@angular/router';
import {HttpClient, HttpHeaders} from '@angular/common/http';

import {Observable, Subscription, throwError} from 'rxjs';
import {catchError, map, timeout, filter} from 'rxjs/operators';

import {TreeNode} from 'primeng/api';

import {MessageService} from 'primeng/api';
import {Message} from 'primeng/api';

import {JwtHelperService} from '@auth0/angular-jwt';

import {Subject} from 'rxjs';

const httpBaseUrl = window.location.protocol + '//' + window.location.hostname + ':' + window.location.port;
// const httpBaseUrl = window.location.protocol + '//' + '10.10.0.1';
const httpUrl = httpBaseUrl + '/api/v1';

const httpOptions = {
    headers: new HttpHeaders({
        'Content-Type': 'application/json'
    })
};


@Injectable({
    providedIn: 'root'
})
export class DeviceService implements OnDestroy {
    /********** localstorage *********/
    public loginState = 'N/A';
    /********** lazyLoad *********/

    public load = 1000;

    /********** Version信息 *********/
    public version = 'V 0.9.5182.15410';

    /********** tabPanel跳转 *********/
    public selectLink: TreeNode;
    public pageIndex: number;
    private routerEventsListener: Subscription;
    public url: string;
    public blockedDocument = false;

    public nodesOne = [
        {
            label: 'System Information',
            icon: 'menu-icon',
            expanded: true,
            data: '/home/system-information',
        },
        {
            label: 'Monitoring',
            icon: 'menu-icon',
            expanded: true,
            data: '/home/monitoring',
            children: [
                {
                    label: 'Motion Status',
                    data: '/home/monitoring/motion-status',
                    styleClass: 'layout-submenu checked-detail'
                },
                {
                    label: 'Heart Rate',
                    data: '/home/monitoring/heart-rate',
                    styleClass: 'layout-submenu checked-detail'
                },
                {
                    label: 'Heart Rate Variability',
                    data: '/home/monitoring/heart-rate-variability',
                    styleClass: 'layout-submenu checked-detail'
                },
                {
                    label: 'Respiration Rate',
                    data: '/home/monitoring/respiration-rate',
                    styleClass: 'layout-submenu checked-detail'
                },
                {
                    label: 'Stroke Volume',
                    data: '/home/monitoring/stroke-volume',
                    styleClass: 'layout-submenu checked-detail'
                },
            ]
        },
        {
            label: 'Alert Notification',
            icon: 'menu-icon',
            expanded: true,
            data: '/home/alert-notification',
            children: [
                {
                    label: 'Service',
                    data: '/home/alert-notification/service',
                    styleClass: 'layout-submenu checked-detail'
                },
                {
                    label: 'Receivers',
                    data: '/home/alert-notification/receivers',
                    styleClass: 'layout-submenu checked-detail'
                }
            ]
        },
        {
            label: 'Device Settings',
            icon: 'menu-icon',
            expanded: true,
            data: '/home/device-settings',
            children: [
                {
                    label: 'Data Communication',
                    data: '/home/device-settings/data-communication',
                    styleClass: 'layout-submenu checked-detail'
                },
                {
                    label: 'Authentication',
                    data: '/home/device-settings/authentication',
                    styleClass: 'layout-submenu checked-detail'
                },
                {label: 'Network', data: '/home/device-settings/network', styleClass: 'layout-submenu checked-detail'},
                {
                    label: 'Firmware Upgrade',
                    data: '/home/device-settings/firmware-upgrade',
                    styleClass: 'layout-submenu checked-detail'
                },

            ]
        },
        /*{
            label: 'Bed Sensor Settings',
            icon: 'menu-icon',
            expanded: true,
            data: '/home/bed-sensor-settings',
            children: [
                {
                    label: 'Calibration',
                    data: '/home/bed-sensor-settings/calibration',
                    styleClass: 'layout-submenu checked-detail'
                },
                {
                    label: 'Advanced Settings',
                    data: '/home/bed-sensor-settings/advanced-settings',
                    styleClass: 'layout-submenu checked-detail'
                }
            ]
        },*/

    ];

    private fuComponentSource = new Subject<any>();
    fuComponent = this.fuComponentSource.asObservable();

    msgs: Message[] = [];

    constructor(private jwtHelperService: JwtHelperService, private router: Router, private route: ActivatedRoute,
                private httpclient: HttpClient, private message: MessageService) {
        this.url = httpUrl;
        this.routerEventsListener = this.router.events
            .pipe(filter((event) => event instanceof NavigationEnd))
            .subscribe((event: NavigationEnd) => {
                // your operation
                this.pageIndex = 0;
                if (event.url === event.urlAfterRedirects) {
                    this.changeMenuStyleByUrl();
                }
            });
    }

    ngOnDestroy(): void {
        this.routerEventsListener.unsubscribe();
    }

    // -----------------------------------------------------------------------------------------------------------
    changeMenuStyleByUrl(): any {
        this.matchUrlWithNodeList(this.router.url, this.nodesOne);
    }

    matchUrlWithNodeList(url, nodeList): any {
        for (let i = 0; i < nodeList.length; i++) {
            if (nodeList[i].data === url) {
                this.selectLink = nodeList[i];
                this.pageIndex = i;
                break;
            }
            if (nodeList[i].children) {
                this.matchUrlWithNodeList(url, nodeList[i].children);
            }
        }
    }

    isValidIP(ip): boolean {
        let res = true;
        const ssIP = ip.trim().split('.');
        if (ssIP.length == 4) {
            for (let i = 0; i < 4; i++) {
                if (ssIP[i].length == 0 || parseInt(ssIP[i]) < 0 || parseInt(ssIP[i]) > 255) {
                    res = false;
                    break;
                }
            }
        }
        else {
            res = false;
        }

        return res;
    }

    formatTime(date, fmt): string {
        const dt = new Date(date);
        const o = {
            'M+': dt.getMonth() + 1, // 月份
            'd+': dt.getDate(), // 日
            'h+': dt.getHours(), // 小时
            'm+': dt.getMinutes(), // 分
            's+': dt.getSeconds(), // 秒
            'q+': Math.floor((dt.getMonth() + 3) / 3), // 季度
            S: dt.getMilliseconds(), // 毫秒
        };
        if (/(y+)/.test(fmt)) {
            fmt = fmt.replace(
                RegExp.$1,
                (dt.getFullYear() + '').substr(4 - RegExp.$1.length)
            );
        }
        for (const k in o) {
            if (new RegExp('(' + k + ')').test(fmt)) {
                fmt = fmt.replace(
                    RegExp.$1,
                    RegExp.$1.length === 1 ? o[k] : ('00' + o[k]).substr(('' + o[k]).length)
                );
            }
        }
        return fmt;
    }

    getTest(): Observable<any> {
        return this.httpclient.get(httpUrl + '/get/test', httpOptions);
    }

    setTest(data): Observable<any> {
        return this.httpclient.post(httpUrl + '/post/test', data, {
            headers: new HttpHeaders({
                'Content-Type': 'application/json',
                'X-Custom-test': 'TEST-DATA'
            })
        });
    }

    // System-Info
    getSystemInformationData(): Observable<any> {
        return this.httpclient.get(httpUrl + '/system-info/get-system-info', httpOptions);
    }

    getBCGData(): Observable<any> {
        return this.httpclient.get(httpUrl + '/system-info/get-BCG-data', httpOptions);
    }

    getWLANAPData(): Observable<any> {
        return this.httpclient.get(httpUrl + '/system-info/get-WLAN-AP-data', httpOptions);
    }

    // Device Settings
    getDataCommunicationSettings(): Observable<any> {
        return this.httpclient.get(httpUrl + '/device-settings/communication-settings', httpOptions);
    }

    // Authentication
    getAuthenticationConfig(): Observable<any> {
        return this.httpclient.get(httpUrl + '/authentication/get-authentication', httpOptions);
    }

    setAuthenticationConfig(data): Observable<any> {
        return this.httpclient.post(httpUrl + '/authentication/set-authentication', {}, {
            headers: new HttpHeaders({
                'Content-Type': 'application/json',
                'X-Custom-name': data.userName,
                'X-Custom-pwd': data.passWord,
            })
        });
    }

    // Network
    getApJson(): Observable<any> {
        return this.httpclient.get(httpUrl + '/get-ap-json', httpOptions);
    }

    getStatusJson(): Observable<any> {
        return this.httpclient.get(httpUrl + '/get-status-json', httpOptions);
    }

    sendRebootRequest(): Observable<any> {
        return this.httpclient.get(httpUrl + '/restart', httpOptions);
    }

    sendFactoryResetRequest(): Observable<any> {
        return this.httpclient.get(httpUrl + '/factory', httpOptions);
    }

    setConnect(ssid, password): Observable<any> {
        return this.httpclient.post(httpBaseUrl + '/connect.json', {}, {
            headers: new HttpHeaders({
                'Content-Type': 'application/json',
                'X-Custom-ssid': ssid,
                'X-Custom-pwd': password,
            })
        });
    }

    setUdpTarget(url): Observable<any> {
        return  this.httpclient.post(httpUrl + '/set-udp', {}, {
            headers: new HttpHeaders({
                'Content-Type': 'application/json',
                'X-Custom-udp': url,
            })
        });
    }

    disConnect(): Observable<any> {
        return this.httpclient.delete(httpBaseUrl + '/connect.json', httpOptions);
    }

    onChangeLanguage(): void {
        setTimeout(() => {
            this.fuComponentSource.next('changeLanguage');
        }, 100);
    }

    rebootDevice(): Observable<any> {
        return this.httpclient.get(httpUrl + '/reboot', httpOptions);
    }
}

